<?php

namespace App\Services\Tools;

use App\Exceptions\BasicException;
use App\Response\Response;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;

class SandPay
{
    public const PRODUCT_ALI_H5 = '02020002';
    public const PRODUCT_WECHAT_H5 = '02010006';
    public const PRODUCT_ALI_APP = '02020004';
    public const PRODUCT_WECHAT_APP = '02010005';

    public function app($orderSn, $money)
    {
        $productCode = self::PRODUCT_ALI_APP . ',' . self::PRODUCT_WECHAT_APP;
        $extra = $this->getAppExtra();
        $params = $this->getParams($productCode, $orderSn, $money, $extra);
        return $params;
    }

    public function wechatApp($orderSn, $money)
    {
        $productCode = self::PRODUCT_WECHAT_APP;
        $extra = $this->getAppExtra();
        $params = $this->getParams($productCode, $orderSn, $money, $extra);
        return $params;
    }

    public function aliApp($orderSn, $money)
    {
        $productCode = self::PRODUCT_ALI_APP;
        $extra = $this->getAppExtra();
        $params = $this->getParams($productCode, $orderSn, $money, $extra);
        return $params;
    }

    public function aliH5($orderSn, $money, $successUrl = '')
    {
        $productCode = self::PRODUCT_ALI_H5;
        $extra = $this->getAliH5Extra();
        $params = $this->getParams($productCode, $orderSn, $money, $extra, $successUrl);
        $query = $this->getH5Params($params);
        $url = 'https://sandcash.mixienet.com.cn/pay/h5/alipay';
        return $url . '?' . $query;
    }

    public function wechatH5($orderSn, $money, $successUrl = '')
    {
        $productCode = self::PRODUCT_WECHAT_H5;
        $extra = $this->getWeChatH5Extra();
        $params = $this->getParams($productCode, $orderSn, $money, $extra, $successUrl);
        $query = $this->getH5Params($params);
        $url = 'https://sandcash.mixienet.com.cn/pay/h5/applet';
        return $url . '?' . $query;
    }


    public function verify($plainText, $sign, $path)
    {
        $resource = openssl_pkey_get_public($path);
        $result = openssl_verify($plainText, base64_decode($sign), $resource);
        openssl_free_key($resource);

        if (!$result) {
            throw new \Exception('签名验证未通过,plainText:' . $plainText . '。sign:' . $sign, '02002');
        }

        return $result;
    }


    private function getAliH5Extra()
    {
        return "";
    }

    private function getWeChatH5Extra()
    {
        return [
            "mer_app_id" => "",
            "openid" => "",
            "buyer_id" => "",
            "wx_app_id" => env("SAND_WECHAT_APP_ID"),
            "gh_ori_id" => env("SAND_GH_ORI_ID"),
            "path_url" => env("SAND_PATH_URL"),  // 拉起小程序页面的可带参路径，不填默认拉起小程序首页
            "miniProgramType" => "0",
            "resourceAppid" => env("SAND_RESOURCE_APP_ID"), // 小程序 AppID
            "resourceEnv" => env("SAND_RESOURCE_ENV"), // 云开发环境 ID
        ];
    }

    private function getAppExtra()
    {
        return [
            "mer_app_id" => "",
            "openid" => "",
            "buyer_id" => "",
            "wx_app_id" => env("SAND_WECHAT_APP_ID"),
            "gh_ori_id" => env("SAND_GH_ORI_ID"),
            "path_url" => env("SAND_PATH_URL"),  // 拉起小程序页面的可带参路径，不填默认拉起小程序首页
            "miniProgramType" => "0",
        ];
    }

    private function getH5Params(array $originParams)
    {
        $paramStr = "";

        $urlArr = ["mer_key","goods_name","notify_url","return_url","pay_extra","meta_option"];

        foreach($originParams as $k => $val) {
            if (in_array($k, $urlArr)) {
                $val = urlencode($val);
            }
            $paramStr .= $k . '=' . $val . '&';
        }

        $newParamStr = substr($paramStr,0,strlen($paramStr)-1);
        return $newParamStr;
    }

    private function getParams($productCode, $orderSn, $money, $payExtra = [], $successUrl = ''): array
    {
        $originParams = [
            "version" => "1.0", // 版本号
            "mer_no" => env("SAND_MER_NO"),  // 商户编号
            "mer_key" => env("SAND_MER_KEY"),  // 商户密钥
            "mer_order_no" => $orderSn, // 商户订单号
            "create_time" => date("YmdHis"),
            "expire_time" => date("YmdHis", strtotime('+3 minute')),
            "order_amt" => $money, // 订单金额（单位:元，1分=0.01元）
            "notify_url" => env("SAND_NOTIFY_URL"),  // 回调地址
            "return_url" => $successUrl, // 支付后返回的商户显示页面
            "create_ip" => "192_168_0_1",
            "goods_name" => "用户充值" . $orderSn, // 商品名称
            "store_id" => "000000", // 门店号
            "product_code" => $productCode,// 支付产品
            "clear_cycle" => "0",
            "pay_extra" => is_string($payExtra)? '': json_encode($payExtra), // 支付拓展
            "accsplit_flag" => "NO",
            "jump_scheme" => "hsyy://scpay", // 跳转scheme
            "sign_type" => "MD5",
        ];
        if($productCode == self::PRODUCT_WECHAT_H5){
            $originParams["gh_static_url"] = env("GH_STATIC_URL");  // 接云函数小程序必填字段
        }

        if(in_array($productCode, [self::PRODUCT_ALI_H5, self::PRODUCT_WECHAT_H5])){
            $originParams['meta_option'] = json_encode([["s" => "", "n" => "", "id" => "", "sc" => "",]]);
        }

        $unSignKeys = ["expire_time","goods_name","product_code","jump_scheme","clear_cycle", "meta_option"];
        $params = [];
        foreach ($originParams as $key => $item) {
            if (!in_array($key, $unSignKeys) && $item != "") {
                $params[$key] = $item;
            }
        }

        ksort($params);

        $str = '';

        foreach($params as $k => $val) {

            $str .= $k . '=' . $val . '&';
        }
        $newstr = substr($str,0,strlen($str)-1);

        $query = $newstr.'&key='.env("SAND_MD5_KEY");

        $sign = strtoupper(md5($query));

        $originParams['sign'] = $sign;
        $originParams['extend'] = '';
        // $originParams['limit_pay'] = 5; // 忽略花呗

        return $originParams;
    }
}